/************************************************************
 *  * EaseMob CONFIDENTIAL 
 * __________________ 
 * Copyright (C) 2013-2014 EaseMob Technologies. All rights reserved. 
 *  
 * NOTICE: All information contained herein is, and remains 
 * the property of EaseMob Technologies.
 * Dissemination of this information or reproduction of this material 
 * is strictly forbidden unless prior written permission is obtained
 * from EaseMob Technologies.
 */
package com.hengtiansoft.lfy.chart.applib.model;

import java.util.HashSet;
import java.util.List;
import java.util.Locale;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Vibrator;
import android.support.v4.app.NotificationCompat;


import com.hengtiansoft.lfy.chart.applib.controller.HXSDKHelper;
import com.hyphenate.chat.EMChatManager;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.util.EMLog;
import com.hyphenate.util.EasyUtils;

/**
 * 新消息提醒class 2.1.8把新消息提示相关的api移除出sdk，方便开发者自由修改 开发者也可以继承此类实现相关的接口
 * 
 * this class is subject to be inherited and implement the relative APIs
 */
public class HXNotifier {
    private final static String TAG = "notify";
    Ringtone ringtone = null;

    protected final static String[] msg_eng = { "sent a message",
            "sent a picture", "sent a voice", "sent location message",
            "sent a video", "sent a file", "%1 contacts sent %2 messages" };
    protected final static String[] msg_ch = { "发来一条消息", "发来一张图片", "发来一段语音",
            "发来位置信息", "发来一个视频", "发来一个文件", "%1个联系人发来%2条消息" };

    protected static int notifyID = 0525; // start notification id
    protected static int foregroundNotifyID = 0555;

    protected NotificationManager notificationManager = null;

    protected HashSet<String> fromUsers = new HashSet<String>();
    protected int notificationNum = 0;

    protected Context appContext;
    protected String packageName;
    protected String[] msgs;
    protected long lastNotifiyTime;
    protected AudioManager audioManager;
    protected Vibrator vibrator;
    protected HXNotificationInfoProvider notificationInfoProvider;

    public HXNotifier() {
    }

    /**
     * 开发者可以重载此函数 this function can be override
     * 
     * @param context
     * @return
     */
    public HXNotifier init(Context context) {
        appContext = context;
        notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);

        packageName = appContext.getApplicationInfo().packageName;
        if (Locale.getDefault().getLanguage().equals("zh")) {
            msgs = msg_ch;
        } else {
            msgs = msg_eng;
        }

        audioManager = (AudioManager) appContext
                .getSystemService(Context.AUDIO_SERVICE);
        vibrator = (Vibrator) appContext
                .getSystemService(Context.VIBRATOR_SERVICE);

        return this;
    }

    /**
     * 开发者可以重载此函数 this function can be override
     */
    public void reset() {
        resetNotificationCount();
        cancelNotificaton();
    }

    void resetNotificationCount() {
        notificationNum = 0;
        fromUsers.clear();
    }

    void cancelNotificaton() {
        if (notificationManager != null)
            notificationManager.cancel(notifyID);
    }

    /**
     * 处理新收到的消息，然后发送通知
     * 
     * 开发者可以重载此函数 this function can be override
     * 
     * @param message
     */
    public synchronized void onNewMsg(EMMessage message) {
        if (message.getBooleanAttribute("em_ignore_notification", false)) {
            return;
        }
        if(!HXSDKHelper.getInstance().getModel().getSettingMsgNotification()){
            return;
        }
        // 判断app是否在后台
        if (!EasyUtils.isAppRunningForeground(appContext)) {
            EMLog.d(TAG, "应用在后台运行");
            sendNotification(message, false);
        } else {
            sendNotification(message, true);
        }

        viberateAndPlayTone(message);
    }

    public synchronized void onNewMesg(List<EMMessage> messages) {
        if (messages.get(messages.size() - 1).getBooleanAttribute("em_ignore_notification", false)) {//判断是否是消息
            return;
        }
        if(!HXSDKHelper.getInstance().getModel().getSettingMsgNotification()){
            return;
        }
        // 判断app是否在后台
        if (!EasyUtils.isAppRunningForeground(appContext)) {
            EMLog.d(TAG, "应用在后台运行");
            sendNotification(messages, false);
        } else {
            sendNotification(messages, true);
        }
        viberateAndPlayTone(messages.get(messages.size() - 1));
    }

    /**
     * 发送通知栏提示 This can be override by subclass to provide customer
     * implementation
     * 
     * @param messages
     * @param isForeground
     */
    protected void sendNotification(List<EMMessage> messages,
            boolean isForeground) {
        for (EMMessage message : messages) {
            if (!isForeground) {
                notificationNum++; //计算消息条数
                fromUsers.add(message.getFrom());//计算联系人数量
            }
        }
        sendNotification(messages.get(messages.size() - 1), isForeground, false);//通知最后一条消息
    }

    protected void sendNotification(EMMessage message, boolean isForeground) {
        sendNotification(message, isForeground, true);
    }

    /**
     * 发送通知栏提示 This can be override by subclass to provide customer
     * implementation
     * 
     * @param message
     */
    protected void sendNotification(EMMessage message, boolean isForeground,
            boolean numIncrease) {
        String username = message.getFrom();
        try {
            String notifyText = username + " ";
            switch (message.getType()) {
            case TXT:
                notifyText += msgs[0];
                break;
            case IMAGE:
                notifyText += msgs[1];
                break;
            case VOICE:

                notifyText += msgs[2];
                break;
            case LOCATION:
                notifyText += msgs[3];
                break;
            case VIDEO:
                notifyText += msgs[4];
                break;
            case FILE:
                notifyText += msgs[5];
                break;
            }

            PackageManager packageManager = appContext.getPackageManager();
            String appname = (String) packageManager
                    .getApplicationLabel(appContext.getApplicationInfo());

            // notification titile
            String contentTitle = appname;
            if (notificationInfoProvider != null) {
                String customNotifyText = notificationInfoProvider
                        .getDisplayedText(message);
                String customCotentTitle = notificationInfoProvider
                        .getTitle(message);
                if (customNotifyText != null) {
                    // 设置自定义的状态栏提示内容
                    notifyText = customNotifyText;//提示消息 显示后几秒消息的文字
                }

                if (customCotentTitle != null) {
                    // 设置自定义的通知栏标题
                    contentTitle = customCotentTitle;
                }
            }

            // create and send notificaiton
            NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( //兼容Notification
                    appContext)
                    .setSmallIcon(appContext.getApplicationInfo().icon)
                    .setWhen(System.currentTimeMillis()).setAutoCancel(true);

            Intent msgIntent = appContext.getPackageManager()
                    .getLaunchIntentForPackage(packageName);
            if (notificationInfoProvider != null) {
                // 设置自定义的notification点击跳转intent
                msgIntent = notificationInfoProvider.getLaunchIntent(message);//获取intent 在DemoHXSDKhelper里面的getLaunchIntent方法
            }

            PendingIntent pendingIntent = PendingIntent.getActivity(appContext,
                    notifyID, msgIntent, PendingIntent.FLAG_UPDATE_CURRENT);//FLAG_UPDATE_CURRENT更新

            if (numIncrease) { //true
                // prepare latest event info section
                if (!isForeground) { //！isForeground true
                    notificationNum++; //消息多少数量
                    fromUsers.add(message.getFrom());//HashSet类型不会重复 所以可以统计有多少联系人
                }
            }

            int fromUsersNum = fromUsers.size();//有多少联系人
            String summaryBody = msgs[6].replaceFirst("%1",
                    Integer.toString(fromUsersNum)).replaceFirst("%2",
                    Integer.toString(notificationNum));//通知栏文字

            if (notificationInfoProvider != null) {
                // lastest text
                String customSummaryBody = notificationInfoProvider
                        .getLatestText(message, fromUsersNum, notificationNum);
                if (customSummaryBody != null) { //这边是null未处理
                    summaryBody = customSummaryBody;
                }

                // small icon
                int smallIcon = notificationInfoProvider.getSmallIcon(message);
                if (smallIcon != 0) { //0未处理
                    mBuilder.setSmallIcon(smallIcon);
                }
            }

            mBuilder.setContentTitle(contentTitle);//龙翻译
            mBuilder.setTicker(notifyText);//qq_fxbuql: 啊是 显示几秒后消失
            mBuilder.setContentText(summaryBody);//1个联系人发来1条消息
            mBuilder.setContentIntent(pendingIntent);//跳转连接
            // mBuilder.setNumber(notificationNum);
            Notification notification = mBuilder.build();

            if (isForeground) {
                notificationManager.notify(foregroundNotifyID, notification);
                notificationManager.cancel(foregroundNotifyID);
            } else {
                notificationManager.notify(notifyID, notification);//使用相同的notifyID会更新Notification
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 手机震动和声音提示
     */
    public void viberateAndPlayTone(EMMessage message) {
        if (message != null) {
            if (message.getBooleanAttribute("em_ignore_notification", false)) {
                return;
            }
        }

        HXSDKModel model = HXSDKHelper.getInstance().getModel(); //DefaultHXSDKModel
        if (!model.getSettingMsgNotification()) { //判断是否有设置震动和声音
            return;
        }

        if (System.currentTimeMillis() - lastNotifiyTime < 1000) {//如果当前和上次相差1秒怎么不进行
            // received new messages within 2 seconds, skip play ringtone
            return;
        }

        try {
            lastNotifiyTime = System.currentTimeMillis();//记录上次时间

            // 判断是否处于静音模式
            if (audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {
                EMLog.e(TAG, "in slient mode now");
                return;
            }

            if (model.getSettingMsgVibrate()) { //是否打开震动
                long[] pattern = new long[] { 0, 180, 80, 120 };
                vibrator.vibrate(pattern, -1);
            }

            if (model.getSettingMsgSound()) {//是否打开声音
                if (ringtone == null) {//播放铃声
                    Uri notificationUri = RingtoneManager
                            .getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

                    ringtone = RingtoneManager.getRingtone(appContext,
                            notificationUri);
                    if (ringtone == null) {
                        EMLog.d(TAG,
                                "cant find ringtone at:"
                                        + notificationUri.getPath());
                        return;
                    }
                }

                if (!ringtone.isPlaying()) {
                    String vendor = Build.MANUFACTURER;

                    ringtone.play(); //播放3秒
                    // for samsung S3, we meet a bug that the phone will
                    // continue ringtone without stop
                    // so add below special handler to stop it after 3s if
                    // needed
                    if (vendor != null
                            && vendor.toLowerCase().contains("samsung")) {
                        Thread ctlThread = new Thread() {
                            public void run() {
                                try {
                                    Thread.sleep(3000);
                                    if (ringtone.isPlaying()) {
                                        ringtone.stop();
                                    }
                                } catch (Exception e) {
                                }
                            }
                        };
                        ctlThread.run();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置NotificationInfoProvider
     * 
     * @param provider
     */
    public void setNotificationInfoProvider(HXNotificationInfoProvider provider) {
        notificationInfoProvider = provider;
    }

    public interface HXNotificationInfoProvider {
        /**
         * 设置发送notification时状态栏提示新消息的内容(比如Xxx发来了一条图片消息)
         * 
         * @param message
         *            接收到的消息
         * @return null为使用默认
         */
        String getDisplayedText(EMMessage message);

        /**
         * 设置notification持续显示的新消息提示(比如2个联系人发来了5条消息)
         * 
         * @param message
         *            接收到的消息
         * @param fromUsersNum
         *            发送人的数量
         * @param messageNum
         *            消息数量
         * @return null为使用默认
         */
        String getLatestText(EMMessage message, int fromUsersNum, int messageNum);

        /**
         * 设置notification标题
         * 
         * @param message
         * @return null为使用默认
         */
        String getTitle(EMMessage message);

        /**
         * 设置小图标
         * 
         * @param message
         * @return 0使用默认图标
         */
        int getSmallIcon(EMMessage message);

        /**
         * 设置notification点击时的跳转intent
         * 
         * @param message
         *            显示在notification上最近的一条消息
         * @return null为使用默认
         */
        Intent getLaunchIntent(EMMessage message);
    }
}
